perm filename FROM.SAI[SAI,LES] blob
sn#836014 filedate 1987-03-09 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00005 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 begin "FROM"
C00004 00003 ! date conversion
C00006 00004 ! procedures
C00009 00005 ! Execution
C00012 ENDMK
C⊗;
begin "FROM"
require "head" source_file;
!
Scans one or more message files containing at most one message per page,
extracts the return address from the "From:" line of each message,
separates the host name from the user ID, and outputs a text file
containing one line per input message in the form
<host> <user ID> <file number>
where <file number> is the integer number of files that have been read,
beginning with 1. The last line of the output file will be a list of the
files read:
<1st file name> <2nd file name> <3rd file name> <etc.>
1987 Feb. 19: First version written by Les Earnest for SU-bboards census.
;
break(inlineups,LF&FF,CR,"IKNS"); ! read a line upper-casified;
scnbrk(tolbroks,"<","","IS"); ! scan to "<";
scnbrk(torbroks,">","","IS"); ! scan to ">";
scnbrk(toats,"@","","IS"); ! scan to "@";
scnbrk(tosemis,":","","IS"); ! scan to ":";
scnbrk(tobangs,"!","","IS"); ! scan to "!";
scnbrk(topers,"%","","IS"); ! scan to "%";
scnbrk(todsss," -/","","IS"); ! scan to " -/";
! date conversion;
boolean proc equiv(STRING A,B); begin
! returns true if A is identical to B[1 to length(A)], neglecting case shifts;
WHILE LN(A) DO IF (LOP(A) LAND '137)≠(LOP(B) land '137) THEN RETURN(FALSE);
RETURN(TRUE)
END;
integer proc match(string m; string array ss; integer sstop); begin
integer mi,mp,ml; ! find unambiguous match between;
mp←0; if (ml←ln(m))=0 then return(0); ! m and one of ss;
for mi←1 thru sstop do if equiv(m,ss[mi]) then
if mp then return(-1) else mp←mi;
return(mp)
end "MATCH";
PRELOAD_WITH "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC";
STRING ARRAY MONTH[1:12];
integer procedure datint(string date); begin
! converts date of form 08-Feb-87 to integer;
integer da,mo;
da←cvd(todsss(date)); ! get day of month;
return(if (mo←match(towhites(date),month,12))≤0 then 0 else
(cvd(date)*12 + mo - 1)*31 + da -1);
end;
! procedures;
integer pageno; ! count of pages;
integer fileno; ! sequential number of file;
string partial; ! last line beginning with "∂";
proc barf(string msg); ! grumble;
print("Page ",pageno,": ",msg,↓,partial,↓);
recursive procedure identify(string froms; boolean prim); begin
! find id & host from "froms" if possible, else use "partial";
procedure badfrom(string msg); begin
barf(msg);
print(froms,↓)
end;
string host,id; ! sender's host & identifier;
string aline;
string bang;
aline←froms;
host←tolbroks(aline);
if brk = "<" then host←torbroks(aline) else begin "nobroket"
aline←host[6 to ∞]; ! skip the "From:";
toprintr(aline);
host←towhites(aline);
end "nobroket";
if host="@" then tosemis(host); ! strip off gateway;
host←towhites(host);
! now we should have id@host;
bang←toats(host);
id←tobangs(bang);
while brk="!" do begin ! translate UUCP into domain;
host←id&">"&host;
id←tobangs(bang);
end;
bang←topers(id); ! look for "%" form;
if ln(id) then host←id&"%"&host;
if ln(host)=0 then begin
if prim then identify(partial,false) else badfrom("No host")
end
else if ln(bang)=0 then barf("No user id")
else cprint(ouch,host," ",bang," ",fileno,↓);
end "IDENTIFY";
procedure sailid; begin ! output SAIL identifier;
string aline,id;
towhites(aline←partial); ! flush date;
toprintr(aline); ! skip spaces;
towhites(aline); ! skip time;
toprintr(aline); ! skip spaces;
id←towhites(aline); ! get id;
if 1<ln(id)≤3 then cprint(ouch,"SAIL.STANFORD.EDU ",id," ",fileno,↓)
else identify(id,false);
end;
! Execution;
string filist;
integer begday,enday;
enton(ask("Finds where and who mail came from.
Output file="));
if (begday←datint(ask("Starting date (e.g. 06-FEB-87) or null: ")))≤0 then
outstr("No date constraint"&↓)
else while (enday←datint(ask("End date: ")))≤0 do outstr("Eh?"&↓);
fileno←0;
filist←"";
while true do begin "main"
string ifile, aline;
boolean fl;
do begin "read"
release (inch);
if ln(ifile←ask("Mail file=")) = 0 then done "main";
open(inch←getchan,"DSK",1,19,0,400,brk,eof);
lookup(inch,ifile,fl);
end "read"
until ¬fl;
filist←filist&" "&ifile;
fileno←fileno + 1;
pageno←0;
! might be better to look for "∂", "From" & "sender" and take the best one;
do begin "file"
boolean fromseen;
pageno←pageno + 1;
fromseen←false;
partial←"";
do begin "page"
integer day;
aline←input(inch,inlineups);
if aline="∂" ∧ (begday≤0 ∨
((day←datint(aline[2 to 10])) ≥ begday) ∧ (day ≤ enday))
then begin "partial"
if ln(partial) ∧ ¬fromseen then sailid;
partial←aline;
fromseen←false;
end
else if equ(aline[1 to 5],"FROM:") ∧ ln(partial) ∧ ¬fromseen
then begin "from"
fromseen←true;
identify(aline,true);
end "from"
end "page"
until brk=ff ∨ eof;
if ln(partial) ∧ ¬fromseen then sailid;
end "file"
until eof;
end "main";
cprint(ouch,filist,↓);
exit;
end